package com.maidou.qiantai.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author maidou
 * @Date 2023/11/23 10:14
 */
@Slf4j
public class BaseExceptionLogAdvice {

    /**
     * 统一打印日志方法
     * @param request 请求信息
     * @param e 异常实体
     * @param clazz 异常类型
     * @param <T> 泛型
     */
    public <T> String logException(HttpServletRequest request, T e, Class<T> clazz) {
        Integer code = null;
        String message = null;
        String LocalizedMessage = null;
        // 获取请求的URL、方法、参数等信息
        String url = request.getRequestURI();
        String method = request.getMethod();
        Map<String, String[]> params = request.getParameterMap();
        try {
            if (clazz.isInstance(BindException.class)) {
                BindException exceptionB = (BindException) e;
                List<ObjectError> allErrors = exceptionB.getBindingResult().getAllErrors();
                List<String> collect = allErrors.stream().map(Index -> {
                    String defaultMessage = Index.getDefaultMessage();
                    return defaultMessage;
                }).collect(Collectors.toList());
                String join = String.join(",", collect);
                log.error("状态码:" + code + "错误信息:" + join + "URL:" + url + "方法:" + method + "参数等信息:" + params.toString() +"描述:" + exceptionB.getMessage());
                return join;
            }
            if (clazz.isInstance(e)) {
                T cast = clazz.cast(e);
                Method getCodeMethod = clazz.getMethod("getCode");
                Method getMessage = clazz.getMethod("getMessage");
                Method getLocalizedMessage = clazz.getMethod("getLocalizedMessage");
                LocalizedMessage = (String) getLocalizedMessage.invoke(cast);
                message = (String) getMessage.invoke(cast);
                code = (int) getCodeMethod.invoke(cast);
            }
            //打印日志
            log.error("状态码:" + code + ",错误信息:" + message + "URL:" + url + "方法:" + method + "参数等信息:" + params.toString() + "描述:" + LocalizedMessage);

        } catch (Exception exception) {
            //打印日志
            log.error("URL:" + url + "方法:" + method + "参数等信息:" + params.toString() + ",错误信息:" + exception.getMessage());
        }
        return null;
    }
}
